﻿using System;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;

namespace project_phoenix.source
{
    class GameplayScreen : GameScreen
    {
        NetworkSession networkSession;
        ContentManager content;
        EntityManager entityManager;
        LevelManager levelManager;

        // Test player stuff
        Death playerDeath;
        War playerWar;
        Famine playerFamine;
        Pestilence playerPest;

        // Debug tests
        Obtainable mMoney;
        Obtainable mHealthPotion;

        Soul testSoul;

        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen(NetworkSession networkSession)
        {
            this.networkSession = networkSession;

            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            // Setup our Player stuff!!
            entityManager = new EntityManager();
            levelManager = new LevelManager();

            mMoney = new Obtainable("Money", new MoneyBehavior(15));
            mHealthPotion = new Obtainable("Health Potion", new PotionBehavior(50));
            playerDeath = new Death();
            playerWar = new War();
            playerFamine = new Famine();
            playerPest = new Pestilence();
            GameGlobals.HudManager.AddElement(new PlayerHudElement(playerDeath, 1));
            GameGlobals.HudManager.AddElement(new PlayerHudElement(playerWar, 4));
            GameGlobals.HudManager.AddElement(new PlayerHudElement(playerFamine, 3));
            GameGlobals.HudManager.AddElement(new PlayerHudElement(playerPest, 2));

            // Lets set up a test soul, we can handle this elsewhere later
            testSoul = new Soul("Soul of the Damned");
            testSoul.AddBuff(new Buff(Buff.StatNames.Defense, 6));
        }

        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            entityManager.LoadContent(content);

            // set our level manager to use the same stuff as the screen manager
            levelManager.LoadContent(ScreenManager.Game.Content);

            GameGlobals.HudManager.LoadContent();

            // this is HORRIBLE - we have to set the sb and content manager since the drawablegamecomponent is being a pain in the ass
            Initialize();
        }

        public void Initialize()
        {
            // Test for now add 4 players!
            entityManager.AddPlayable(playerDeath);
            entityManager.AddPlayable(playerWar);
            entityManager.AddPlayable(playerFamine);
            entityManager.AddPlayable(playerPest);
            //entityManager.Add

            levelManager.LoadTestLevel();

            entityManager.SpawnPlayer(0, new Vector2(20, 600));
        }
        

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            entityManager.Update(gameTime);
            levelManager.UpdateLevel(entityManager.Players, gameTime);
            GameGlobals.HudManager.Update(gameTime);
            if (GameSystems.Input.CheckKeyPress(Keys.F))
            {
                //GameSystems.Particles.BasicTrigger(new Vector2(500.0f, 300.0f), Color.Red, 600, new Vector2(1.0f, 5.0f), new Vector2(1.0f, 50.0f), 0.5f);
                playerDeath.ModHealth(-3);
            }
            if (GameSystems.Input.CheckKeyPress(Keys.H))
            {
                mHealthPotion.PickUp(playerDeath);
                mHealthPotion.Use(playerDeath);
            }
            if (GameSystems.Input.CheckKeyPress(Keys.M))
            {
                mMoney.PickUp(playerDeath);
            }
            if (GameSystems.Input.CheckKeyPress(Keys.S))
            {
                testSoul.Equip(playerDeath);
            }
            if (GameSystems.Input.CheckKeyPress(Keys.R))
            {
                testSoul.UnEquip(playerDeath);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            //GameSystems.Graphics.ClearScreenToColor(Color.Black);

            GameSystems.Graphics.BeginSprites();

                levelManager.DrawLevel(gameTime);
                GameSystems.Particles.Draw();
                entityManager.Draw(gameTime);
                levelManager.DrawLevelForeground(gameTime);
                GameGlobals.HudManager.Draw();
            GameSystems.Graphics.EndSprites();
        }

        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            if (ControllingPlayer.HasValue)
            {
                // In single player games, handle input for the controlling player.
                HandlePlayerInput(input, ControllingPlayer.Value);
            }
            else if (networkSession != null)
            {
                // In network game modes, handle input for all the
                // local players who are participating in the session.
                foreach (LocalNetworkGamer gamer in networkSession.LocalGamers)
                {
                    if (!HandlePlayerInput(input, gamer.SignedInGamer.PlayerIndex))
                        break;
                }
            }
        }
        /// <summary>
        /// Handles input for the specified player. In local game modes, this is called
        /// just once for the controlling player. In network modes, it can be called
        /// more than once if there are multiple profiles playing on the local machine.
        /// Returns true if we should continue to handle input for subsequent players,
        /// or false if this player has paused the game.
        /// </summary>
        bool HandlePlayerInput(InputState input, PlayerIndex playerIndex)
        {
            // Look up inputs for the specified player profile.
            //KeyboardState keyboardState = input.CurrentKeyboardStates[(int)playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[(int)playerIndex];

            //KeyboardState PrevKeyboardState = input.LastKeyboardStates[(int)playerIndex];
            GamePadState PrevGamePadState = input.LastGamePadStates[(int)playerIndex];



            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected &&
                                       input.GamePadWasConnected[(int)playerIndex];

            if (input.IsPauseGame(playerIndex) || gamePadDisconnected)
            {
                // TODO : add the pause screen
                ScreenManager.AddScreen(new PauseMenuScreen(networkSession), playerIndex);
                return false;
            }

            // Player movement

            // dont move if we are attacking
            if (GameSystems.Input.CheckKeyPressContinuous(Keys.Left))
                entityManager.MovePlayerLeft((int)playerIndex);
            if (GameSystems.Input.CheckKeyPressContinuous(Keys.Right))
                entityManager.MovePlayerRight((int)playerIndex);
            if (GameSystems.Input.CheckKeyPressContinuous(Keys.Up))
                entityManager.MovePlayerUp((int)playerIndex);
            if (GameSystems.Input.CheckKeyPressContinuous(Keys.Down))
                entityManager.MovePlayerDown((int)playerIndex);

            if (GameSystems.Input.CheckKeyPress(Keys.A))
            {
                entityManager.Attack((int)playerIndex);
            }

            if (GameSystems.Input.CheckKeyPress(Keys.E))
            {
                entityManager.SpawnNPE("Imp", new Vector2(GameGlobals.RNG.Next(300, 900),GameGlobals.RNG.Next(300, 500)));
            }

            return true;
        }

    }
}
